package com.trj.scaleview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.zxy.tiny.Tiny;
import com.zxy.tiny.callback.BitmapCallback;

/**
 * @author TRJ
 * @date 2018/6/21
 * Description:
 */
public class ScaleView extends View {

    private Bitmap mBitmap;// 位图对象

    private PointData mPointData;

    private int width = 1080;
    private int height;

    private int bitmapWidth = 1080;

    private float scale = 1;
    private Paint mBgPaint;
    private Paint mTextPaint;

    public ScaleView(Context context) {
        this(context, null);
    }

    public ScaleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public void setData(PointData pointData) {
        mPointData = pointData;
        scale = Float.valueOf(width) / Float.valueOf(mPointData.pic_width);
        height = (int) (mPointData.pic_height / scale);

        Tiny.BitmapCompressOptions options = new Tiny.BitmapCompressOptions();
        options.width = width;
        options.height = height;
        Tiny.getInstance().source(R.mipmap.ic_source).asBitmap().compress(new BitmapCallback() {
            @Override
            public void callback(boolean isSuccess, Bitmap bitmap, Throwable t) {
                mBitmap = bitmap;
                Log.i("callback", "" + bitmap.getWidth());
                bitmapWidth = bitmap.getWidth();
                postInvalidate();
            }
        });

        mBgPaint = new Paint();
        mBgPaint.setColor(Color.RED);
        mTextPaint = new Paint();
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        //或者可以直接canvas.save()
        canvas.save(Canvas.MATRIX_SAVE_FLAG);

        canvas.setMatrix(matrix);
        canvas.scale(Float.valueOf(width) / Float.valueOf(bitmapWidth), Float.valueOf(width) / Float.valueOf(bitmapWidth));


//        canvas.scale(2, 2);

        //缩放中心在左上角
        if (mBitmap != null) {
            canvas.drawBitmap(mBitmap, 0, 0, null);
            drawRedPoint(canvas);
        }
        canvas.restore();
    }

    private void drawRedPoint(Canvas canvas) {
        for (PointData.HotSpotsBean bean : mPointData.hot_spots) {
            float x = bean.pos_x * scale / (Float.valueOf(width) / Float.valueOf(bitmapWidth));
            float y = bean.pos_y * scale / (Float.valueOf(width) / Float.valueOf(bitmapWidth));
            float rw = bean.reg_w * scale / (Float.valueOf(width) / Float.valueOf(bitmapWidth));
            float rh = bean.reg_h * scale / (Float.valueOf(width) / Float.valueOf(bitmapWidth));
            canvas.drawRect(x, y, x + rw, y + rh, mBgPaint);
            mTextPaint.setTextSize(20);

            float baseLineY = Math.abs(mTextPaint.ascent() + mTextPaint.descent()) / 2;

            canvas.drawText(String.valueOf(bean.posno), x + rw / 2, y + rh / 2 + baseLineY, mTextPaint);
        }
    }


    /**
     * 记录是拖拉照片模式还是放大缩小照片模式
     */
    private int mode = 0;// 初始状态
    /**
     * 拖拉照片模式
     */
    private static final int MODE_DRAG = 1;
    /**
     * 放大缩小照片模式
     */
    private static final int MODE_ZOOM = 2;

    /**
     * 用于记录开始时候的坐标位置
     */
    private PointF startPoint = new PointF();
    /**
     * 用于记录拖拉图片移动的坐标位置
     */
    private Matrix matrix = new Matrix();
    /**
     * 用于记录图片要进行拖拉时候的坐标位置
     */
    private Matrix currentMatrix = new Matrix();

    /**
     * 两个手指的开始距离
     */
    private float startDis;
    /**
     * 两个手指的中间点
     */
    private PointF midPoint;


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        /** 通过与运算保留最后八位 MotionEvent.ACTION_MASK = 255 */
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            // 手指压下屏幕
            case MotionEvent.ACTION_DOWN:
                float[] points = new float[2];
                points[0] = event.getX();
                points[1] = event.getY();
                Matrix m = new Matrix();
                m.set(matrix);
                m.invert(m);
                m.mapPoints(points);
                Log.i("down", "x = " +matrix.toString());
                Log.i("down", "x = " + event.getX() + "  y = " + event.getY());
                Log.i("down", "x = " + points[0] + "  y = " + points[1]);
                mode = MODE_DRAG;
                // 记录ImageView当前的移动位置
//                currentMatrix.set(ImageView matrix);
                currentMatrix.set(matrix);
                startPoint.set(event.getX(), event.getY());
                break;
            // 手指在屏幕上移动，改事件会被不断触发
            case MotionEvent.ACTION_MOVE:
                // 拖拉图片
                if (mode == MODE_DRAG) {
                    float dx = event.getX() - startPoint.x; // 得到x轴的移动距离
                    float dy = event.getY() - startPoint.y; // 得到x轴的移动距离
                    // 在没有移动之前的位置上进行移动
                    matrix.set(currentMatrix);
                    matrix.postTranslate(dx, dy);
                }
                // 放大缩小图片
                else if (mode == MODE_ZOOM) {
                    float endDis = distance(event);// 结束距离
                    if (endDis > 10f) { // 两个手指并拢在一起的时候像素大于10
                        float scale = endDis / startDis;// 得到缩放倍数
                        matrix.set(currentMatrix);
                        matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                    }
                }
                break;
            // 手指离开屏幕
            case MotionEvent.ACTION_UP:
                // 当触点离开屏幕，但是屏幕上还有触点(手指)
            case MotionEvent.ACTION_POINTER_UP:
                mode = 0;
                break;
            // 当屏幕上已经有触点(手指)，再有一个触点压下屏幕
            case MotionEvent.ACTION_POINTER_DOWN:
                mode = MODE_ZOOM;
                /** 计算两个手指间的距离 */
                startDis = distance(event);
                /** 计算两个手指间的中间点 */
                if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
                    midPoint = mid(event);
                    //记录当前ImageView的缩放倍数
//                    currentMatrix.set(imageView.getImageMatrix());
                    currentMatrix.set(matrix);
                }
                break;
        }
//        imageView.setImageMatrix(matrix);
        postInvalidate();
        return true;
    }

    /**
     * 计算两个手指间的距离
     */
    private float distance(MotionEvent event) {
        float dx = event.getX(1) - event.getX(0);
        float dy = event.getY(1) - event.getY(0);
        /** 使用勾股定理返回两点之间的距离 */
        return (float) Math.sqrt(dx * dx + dy * dy);
    }

    /**
     * 计算两个手指间的中间点
     */
    private PointF mid(MotionEvent event) {
        float midX = (event.getX(1) + event.getX(0)) / 2;
        float midY = (event.getY(1) + event.getY(0)) / 2;
        return new PointF(midX, midY);
    }

}
